package com.bing.habit.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.bing.habit.exception.BusinessException;
import com.bing.habit.exception.UploadException;
import com.bing.habit.mapper.ClockinLogDAO;
import com.bing.habit.entity.ClockinLog;
import com.bing.habit.service.ClockInLogService;
import com.bing.habit.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class ClockInLogServiceImpl implements ClockInLogService {

    @Autowired
    ClockinLogDAO clockinLogDAO;
    //oss相关配置
    @Resource
    private OSS ossClient;
    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;
    @Value("${spring.cloud.alicloud.secret-key}")
    private String secretId;
    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;
    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;
    //切换上传文件
    @Value("${image.save.uploadSwitch}")
    private boolean uploadSwitch;
    //本地上传路径
    @Value("${image.save.path}")
    private String imagePath;
    //本地上传文件url,用于静态分发器读取
    private String base = "http://127.0.0.1:8443/habit/api/file/";

    @Override
    public void addOrUpdate(ClockinLog clockinLog) {
        if (clockinLog.getId() != 0) {
            clockinLogDAO.updateById(clockinLog);
        } else {
            clockinLogDAO.insert(clockinLog);
        }
    }

    @Override
    public void delete(int id) {
        clockinLogDAO.deleteById(id);
    }

    @Override
    public ClockinLog get(int id) {
        return clockinLogDAO.selectById(id);
    }

    @Override
    public List<ClockinLog> listByHabit(int hid) {
        return clockinLogDAO.findAllByHidOrderByCreateTimeDesc(hid);
    }

    @Override
    public boolean listByToday(int hid) {
        String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        if (clockinLogDAO.listDay(hid, today) != null) {
            return true;
        }
        return false;
    }

    @Override
    public void deleteByHidAndToday(int hid) {
        String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        ClockinLog c = clockinLogDAO.listDay(hid, today);
        if (c != null) {
            clockinLogDAO.deleteById(c.getId());
        }
    }

    /**
     * @description: 文件上传操作[本地路径/阿里云oss]
     * @author: xujiabing
     * @date: 2024-09-27 15:01
     * @param: file
     * @return: java.lang.String
     */
    @Override
    public String uploadFile(MultipartFile file) throws IOException {

        try {
            if (uploadSwitch) {//上传到本地
                String folder = imagePath;
                File imageFolder = new File(folder);
                //生成资源路径文件名称
                File f = new File(imageFolder,
                        StringUtils.getRandomString(6) + file.getOriginalFilename()
                                .substring(file.getOriginalFilename().length() - 4));
                //路径不存在，就创建
                if (!f.getParentFile().exists()) {
                    f.getParentFile().mkdirs();
                }
                try {
                    file.transferTo(f);
                    return this.base + f.getName();
                } catch (IOException e) {
                    e.printStackTrace();
                    return "";
                }
            } else {//上传到oss

                //以日期作为文件夹名称
                String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                String dir = format + "/";

                //获取上传文件输入流
                InputStream inputStream = file.getInputStream();
                //获取上传文件名称-[微信上传加密]
                String fileName = Objects.requireNonNull(file.getOriginalFilename())
                        .substring(0, 6) + file.getContentType()
                        .replaceAll("image/", ".");

                //最终上传路径
                String path = dir + fileName;
                //创建OSSClient实例。
                OSS ossClient = new OSSClient(endpoint, accessId, secretId);

                //调用oss方法上传到阿里云
                //第一个参数：Bucket名称
                //第二个参数：上传到oss文件路径和文件名称
                //第三个参数：上传文件输入流
                ossClient.putObject(bucket, path, inputStream);

                //把上传后把文件url返回
                String url = "https://" + bucket + "." + endpoint + "/" + path;
                //关闭OSSClient
                ossClient.shutdown();

                return url;
            }
        } catch (UploadException e) {
            throw new UploadException("上传文件过程异常");
        }
    }

    /**
     * @description: 删除打卡日志时，删除上传的图片
     * @author: xujiabing
     * @date: 2024-09-30 15:10
     * @param: filePath
     * @return: void
     */
    @Override
    @Async("asyncTaskExecutor")
    public void delUploadFile(String fileName) {
        //判断文件名称是上传到本地还是oss
        if (fileName.contains(this.base)) {
            // 指定要删除的图片文件的路径
            //http://127.0.0.1:8443/habit/api/file/sn7lm6.png
            String name = fileName.substring(fileName.lastIndexOf("/") + 1);
            String realFilePath = this.imagePath + "\\" + name;
            File file = new File(realFilePath);
            //检查文件是否存在
            if (file.exists()) {
                boolean isDelete = file.delete();
                if (!isDelete) {
                    throw new BusinessException("删除本地图片失败: " + fileName);
                } else {
                    log.info("成功删除本地文件 = {}",fileName);
                }
            } else {
                throw new BusinessException("本地文件不存在: " + fileName);
            }
        } else if (fileName.contains(this.endpoint)) {//oss
            this.deleteOssFile(fileName);
        } else {
            throw new BusinessException("图片资源路径不合法: " + fileName);
        }
    }

    /**
     * @description: oss删除图片资源
     * @author: xujiabing
     * @date: 2024-09-30 22:02
     * @param: objectName
     * @return: void
     */
    public void deleteOssFile(String objectName) {
        try {
            //创建OSSClient实例
            OSSClient ossClient = new OSSClient(endpoint, accessId, secretId);
            // 根据BucketName,objectName删除文件
            ossClient.deleteObject(bucket
                    , objectName.replace("https://" + bucket + "." + endpoint + "/",""));
            log.info("成功删除oss资源文件 = {}",objectName);
        } catch (OSSException e) {
            throw new BusinessException("oss删除文件异常: " + objectName);
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * @description: 批量删除操作
     * @author: xujiabing
     * @date: 2024-09-29 9:01
     * @param: ids
     * @return: void
     */
    @Override
    public void deleteBatchIds(List<Integer> ids) {
        clockinLogDAO.deleteBatchIds(ids);
    }
}
